<template>
  <div class="graph-wrapper">
    <div class="control-box">
      <el-select v-model="layout" @change="changeLayout" placeholder="请选择布局" size="mini">
        <el-option label="层次布局" value="dagre"></el-option>
        <el-option label="网格布局" value="grid"></el-option>
        <el-option label="力导向布局" value="force"></el-option>
        <el-option label="环形布局" value="circular"></el-option>
      </el-select>
      <el-button @click="saveVisible = true" size="mini" v-if="type">保存当前图谱</el-button>
    </div>
    <div class="graph-container" ref="graphContainer"></div>

    <!-- 弹窗 -->
    <el-dialog title="保存图谱" :visible.sync="saveVisible" width="30%" :close-on-click-modal="false">
      <el-form ref="form" :model="form" label-width="70px">
        <el-form-item label="图谱名称">
          <el-input v-model="form.name"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="saveVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveGraphData">确 定</el-button>
      </span>
    </el-dialog>


    <!-- 抽屉 -->
    <el-drawer title="查看详情" :visible.sync="infoVisible">
      <div style="padding: 0 20px;">
        <el-descriptions class="margin-top" title="" :column="1" size="medium" border>
          <el-descriptions-item :label="key" v-for="(value, key) in cInfo" :key="key">{{ value
            }}</el-descriptions-item>
        </el-descriptions>
      </div>
    </el-drawer>
  </div>
</template>

<script>
import G6 from '@antv/g6';

export default {
  name: 'graph',
  props: {
    data: {
      type: Object,
      required: true,
    },
    type: {
      type: String,
      default: "",
    }
  },
  watch: {
    // data: {
    //   deep: true,
    //   handler(newData) {
    //     if (this.graph) {
    //       console.log("newData", newData)
    //       const newDataCopy = this.$cloneDeep(newData); // 深拷贝数据
    //       this.graph.changeData(newDataCopy);
    //     }
    //   },
    // },
  },
  data() {
    return {
      graph: null,
      saveVisible: false,
      form: {},
      infoVisible: false,
      cInfo: {}, //当前节点或边信息
      layout: 'force', //当前布局
    }
  },
  mounted() {
    this.initGraph();
    window.addEventListener('resize', this.handleResize);
  },
  methods: {
    setData(newDataCopy) {
      // const newDataCopy = this.$cloneDeep(newData); // 深拷贝数据
      this.graph.changeData(newDataCopy);
    },
    // 点击节点
    nodeClick(e) {
      const info = e.item.getModel().info;
      if (info.isFirst) {
        // 是第一个节点
        this.$emit("getChildren", info.Group_id)
        return
      }
      this.cInfo = info
      this.infoVisible = true
    },
    // 点击边
    edgeClick(e) {
      const info = e.item.getModel().info;
      this.cInfo = info
      this.infoVisible = true
    },
    initGraph() {
      const colors = [
        '#000033', '#000066', '#000099', '#0000cc', '#0000ff',
        '#003300', '#003333', '#003366', '#003399', '#0033cc', '#0033ff',
        '#006600', '#006633', '#006666', '#006699', '#0066cc', '#0066ff',
        '#009900', '#009933', '#009966', '#009999', '#0099cc', '#0099ff',
        '#00cc00', '#00cc33', '#00cc66', '#00cc99', '#00cccc', '#00ccff',
        '#00ff00', '#00ff33', '#00ff66', '#00ff99', '#00ffcc', '#00ffff',
        '#330000', '#330033', '#330066', '#330099', '#3300cc', '#3300ff',
        '#333300', '#333333', '#333366', '#333399', '#3333cc', '#3333ff',
        '#336600', '#336633', '#336666', '#336699', '#3366cc', '#3366ff',
        '#339900', '#339933', '#339966', '#339999', '#3399cc', '#3399ff',
        '#33cc00', '#33cc33', '#33cc66', '#33cc99', '#33cccc', '#33ccff',
        '#33ff00', '#33ff33', '#33ff66', '#33ff99', '#33ffcc', '#33ffff',
        '#660000', '#660033', '#660066', '#660099', '#6600cc', '#6600ff',
        '#663300', '#663333', '#663366', '#663399', '#6633cc', '#6633ff',
        '#666600', '#666633', '#666666', '#666699', '#6666cc', '#6666ff',
        '#669900', '#669933', '#669966', '#669999', '#6699cc', '#6699ff',
        '#66cc00', '#66cc33', '#66cc66', '#66cc99', '#66cccc', '#66ccff',
        '#66ff00', '#66ff33', '#66ff66', '#66ff99', '#66ffcc', '#66ffff',
        '#990000', '#990033', '#990066', '#990099', '#9900cc', '#9900ff',
        '#993300', '#993333', '#993366', '#993399', '#9933cc', '#9933ff',
        '#996600', '#996633', '#996666', '#996699', '#9966cc', '#9966ff',
        '#999900', '#999933', '#999966', '#999999', '#9999cc', '#9999ff',
        '#99cc00', '#99cc33', '#99cc66', '#99cc99', '#99cccc', '#99ccff',
        '#99ff00', '#99ff33', '#99ff66', '#99ff99', '#99ffcc', '#99ffff',
        '#cc0000', '#cc0033', '#cc0066', '#cc0099', '#cc00ff',
        '#cc3300', '#cc3333', '#cc3366', '#cc3399', '#cc33cc', '#cc33ff',
        '#cc6600', '#cc6633', '#cc6666', '#cc6699', '#cc66cc', '#cc66ff',
        '#cc9900', '#cc9933', '#cc9966', '#cc9999', '#cc99cc', '#cc99ff',
        '#cccc00', '#cccc33', '#cccc66', '#cccc99', '#cccccc', '#ccccff',
        '#ccffcc', '#ccffff', '#ccff00', '#ccff33', '#ccff66', '#ccff99',
        '#ccffcc', '#ccffff', '#ff0000', '#ff0033', '#ff0066', '#ff0099',
        '#ff00cc', '#ff00ff', '#ff3300', '#ff3333', '#ff3366', '#ff3399',
        '#ff33cc', '#ff33ff', '#ff6600', '#ff6633', '#ff6666', '#ff6699',
        '#ff66cc', '#ff66ff', '#ff9900', '#ff9933', '#ff9966', '#ff9999',
        '#ff99cc', '#ff99ff', '#ffcc00', '#ffcc33', '#ffcc66', '#ffcc99',
        '#ffcccc', '#ffccff'
      ];
      const container = this.$refs.graphContainer
      const menu = this.getMenu()
      const graph = new G6.Graph({
        container: container,
        width: container.clientWidth,
        height: container.clientHeight,
        fitCenter: true,
        plugins: [menu], // 配置 Menu 插件
        layout: {
          type: 'force2',
          center: [200, 200],     // 可选，默认为图的中心
          linkDistance: 50,         // 可选，边长
          nodeStrength: 30,         // 可选
          edgeStrength: 0.1,        // 可选
          nodeSize: 30,             // 可选
          animate: true,
        },
        defaultNode: {
          type: 'circle',
          size: '60',
          style: {
            fill: '#FFFFFF', //节点填充色
            stroke: '#87EAEF', //节点的描边颜色
            lineWidth: 3, //描边宽度
          },
          labelCfg: {
            position: 'center',
            style: {
              fontSize: 10,
            }
          },
        },
        defaultEdge: {
          labelCfg: {
            autoRotate: true,
            style: {
              fill: '#1890ff',
              fontSize: 14,
              background: {
                fill: '#ffffff',
                stroke: '#9EC9FF',
                padding: [2, 2, 2, 2],
                radius: 2,
              },
            },
          },
        },
        modes: {
          default: ['drag-canvas', 'drag-node', 'zoom-canvas'],
        },
      });
      // graph.node((node) => {
      //   const colorIndex = node.info.Group_id % colors.length; // 根据 group_id 确定颜色
      //   console.log("colorIndex", colorIndex, node.info.Group_id)
      //   console.log("colors[colorIndex]", colors[colorIndex])
      //   return {
      //     id: node.id,
      //     fill: colors[colorIndex] || '#9EC9FF',
      //     stroke: colors[colorIndex] || '#9EC9FF',
      //     lineWidth: 3,
      //   }
      // });

      // 鼠标左键单击节点时触发
      graph.on('node:click', (evt) => {
        this.nodeClick(evt)
      })

      // 鼠标双击节点
      graph.on('node:dblclick', (evt) => {
        this.nodeDbClick(evt)
      })

      // 鼠标左键单击边时触发
      graph.on('edge:click', (evt) => {
        this.edgeClick(evt)
      })


      this.graph = graph
      this.graph.data(this.data);
      this.graph.render();
    },
    // 获取右键菜单
    getMenu() {
      return new G6.Menu({
        offsetX: 6,
        offsetX: 10,
        itemTypes: ['node'],
        getContent: (evt) => {
          const item = evt.item.getModel()
          const children = item.children
          console.log("右键节点信息", item)
          if (!children) {
            return ""
          }
          let allNum = 0
          let html = ""
          const list = children.map(item => {
            const type = item.type
            const num = item.num
            allNum = allNum + (+num)
            let numText
            if (num > 15) {
              numText = `15（${num}）`
            }else{
              numText = num
            }
            html += `<li data-button="drillDown" data-type="${type}">${type}：${numText}</li>`
            return {
              type,
              num
            }
          })
          return `<ul class="g6-menu">
                        <li data-button="drillDown" data-type="all">全量：${allNum}</li>
                        ${html}
                    </ul>`;
        },
        handleMenuClick: (target, node) => {
          const button = target.getAttribute('data-button');
          const item = node.getModel()
          console.log("item", item)
          if (button === 'drillDown') {
            const type = target.getAttribute('data-type');
            const nodeId = node.getID()
            const curLabel = item.info.label
            if (type == 'all') {
              console.log("下钻全部")
              this.$emit('renren', { id: nodeId, label: curLabel, isAll: true })
            } else {
              console.log("下钻某个类型", type)
              this.$emit('renren', { id: nodeId, label: curLabel, label1: type, isAll: false })
            }
          } else if (button === 'otherAction') {
            console.log('其他操作');
            this.graph.updateLayout({
              type: 'force',
            });
          }
        },
      })
    },
    // 保存当前图谱
    async saveGraphData() {
      let graphInfo = this.graph.save()
      let postData = {
        spaceName: this.type,
        graphInfo: graphInfo,
        graphName: this.form.name
      }
      console.log("postData", postData)
      const res = await this.$http.postJson('/api/saveGraph', postData)
      this.$message.success("操作成功")
      this.saveVisible = false
      this.$emit("getGraphList")
    },
    // 改变图布局
    changeLayout(layoutType) {
      let newData = this.graph.save()
      const layoutConfig = {
        type: layoutType,
      };

      if (layoutType === 'force') {
        layoutConfig.preventOverlap = true;
        layoutConfig.linkDistance = 100; // 节点之间的距离
        layoutConfig.nodeStrength = -30; // 节点之间的排斥力
        layoutConfig.edgeStrength = 0.1; // 边的引力
        layoutConfig.gravity = 10; // 图的重力
      }

      this.graph.updateLayout(layoutConfig);

      // 重新加载数据并渲染图以确保布局切换正常
      this.graph.data(newData);
      this.graph.render();
    },
    // 重新设置大小
    handleResize() {
      const container = this.$refs.graphContainer
      this.graph.changeSize(container.clientWidth, container.clientHeight);
    },
  }
}
</script>

<style>
.graph-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
  box-sizing: border-box;
}

.control-box {
  position: absolute;
  right: 0;
  top: 0;
}

.graph-container {
  background-color: rgb(237, 237, 237);
  width: 100%;
  height: 100%;
}

.g6-menu {
  list-style: none;
  margin: 0;
  padding: 0;
}

.g6-menu li {
  padding: 10px 20px;
  cursor: pointer;
  transition: background-color 0.3s;
}

.g6-menu li:hover {
  background-color: #f5f7fa;
}

.g6-component-contextmenu {
  padding: 0;
}
</style>